home *** CD-ROM | disk | FTP | other *** search
- /* TBinderListConnectInspector.m
- * Written By: Thomas Burkholder
- *
- * You may freely copy, distribute, and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to its
- * fitness for any particular use.
- */
-
-
- #import "TBinderListConnectInspector.h"
- #import "TConnector.h"
- #import "TDataSourceConnector.h"
- #import "TBinderList.h"
- #import "TBinder.h"
- #import "TBinderInspector.h"
- #import "SelPairAgent.h"
- #import "SelectorBrowsingFunctions.h"
- #import "../Utilities.subproj/SortedList.h"
- #import "../Utilities.subproj/ConnectorAgent.h"
- #import "../Utilities.subproj/ClassAdditions.h"
- #import "../Utilities.subproj/SortedStorage.h"
-
- static BOOL selecting;
-
- @implementation TBinderListConnectInspector
-
- id getDSConnectorForSource(id anObject)
- {
- id sList = [[List alloc] init];
- id dsConnector;
-
- [[NXApp activeDocument] listConnectors:sList forSource:anObject
- filterClass:[TDataSourceConnector class]];
- dsConnector = [sList objectAt:0];
- [sList free];
- return dsConnector;
- }
-
- id getTConnectorForDestination(id anObject)
- {
- id sList = [[List alloc] init];
- id tConnector;
-
- [[NXApp activeDocument] listConnectors:sList forDestination:anObject
- filterClass:[TConnector class]];
- tConnector = [sList objectAt:0];
- [sList free];
- return tConnector;
- }
-
- - init
- {
- char buf[MAXPATHLEN + 1];
- id bundle;
-
- [super init];
-
- bundle = [NXBundle bundleForClass:[TBinderList class]];
- [bundle getPath:buf forResource:"TBinderListConnectInspector" ofType:"nib"];
- [NXApp loadNibFile:buf owner:self withNames:NO fromZone:[self zone]];
- [browser setDoubleAction:@selector(inspectBinderAfterDelay:)];
- [connectorList setAgent:[[ConnectorAgent alloc] init]];
- [accessorBrowser getTitleFromPreviousColumn:NO];
- [accessorBrowser setTitle:"DataSource" ofColumn:0];
- [accessorStorage setAgent:
- [[SelPairAgent alloc] initFrom:accessorStorage]];
- [browser setEmptySelectionEnabled:YES];
- [browser loadColumnZero];
-
- selecting = NO;
-
- return self;
- }
-
- - inspectorView
- {
- return inspectorView;
- }
-
- - inspectBinderAfterDelay:sender
- {
- [self perform:@selector(inspectBinder:) with:sender afterDelay:0
- cancelPrevious:NO];
- return self;
- }
-
- - inspectBinder:sender
- {
- id isv = [inspectorView superview];
- id binderView = [binderInspector inspectorView];
- id conn=[connectorList objectAt:[[browser matrixInColumn:0]selectedRow]];
-
- [[isv window] disableFlushWindow];
- [isv replaceSubview:inspectorView with:binderView];
- [binderInspector inspectBinder:[conn binder] andReturnTo:self];
- [[binderView window] display];
- [[binderView window] reenableFlushWindow];
- [[binderView window] flushWindow];
- return self;
- }
-
- - selectAccessor:sender
- {
- id conn;
- int col;
-
- // if there's no connection to apply it to, return.
- if (![[browser matrixInColumn:0] selectedCell])
- return self;
-
- // okay, we need to change the connection's binder:
- col = [accessorBrowser selectedColumn];
- conn = [connectorList objectAt:[[browser matrixInColumn:0] selectedRow]];
- if (0==col) {
- SEL s = sel_getUid([[[accessorBrowser matrixInColumn:0]
- selectedCell] stringValue]);
- if (s!=[[conn binder] dataSourceAccessor]) {
- [[conn binder] setDataSourceAccessor:s];
- [[conn binder] setDataSourceModifier:modifierFor(s)];
-
- // lets try not to lose the interfaceAccessor:
- [self showConnection:conn];
- if (![accessorBrowser selectedColumn]) {
- [[conn binder] setInterfaceAccessor:(SEL)0];
- [[conn binder] setInterfaceModifier:(SEL)0];
- }
- }
- } else if (1==col) {
- SEL s = sel_getUid([[[accessorBrowser matrixInColumn:1]
- selectedCell] stringValue]);
- [[conn binder] setInterfaceAccessor:s];
- [[conn binder] setInterfaceModifier:modifierFor(s)];
- } else {
- [[conn binder] setDataSourceAccessor:(SEL)0];
- [[conn binder] setDataSourceModifier:(SEL)0];
-
- [[conn binder] setInterfaceAccessor:(SEL)0];
- [[conn binder] setInterfaceModifier:(SEL)0];
- }
- return self;
- }
-
- - selectDSConnection:sender
- {
- id dsConnector = getDSConnectorForSource(object);
- selecting = YES;
- if ([sourceDisplayButton state]) {
- [NXApp displayConnectionBetween:[dsConnector source] and:
- [dsConnector destination]];
- } else {
- [NXApp stopConnecting];
- }
- return self;
- }
-
- - dataSourceOk:sender
- {
- id dsConnector = getDSConnectorForSource(object);
-
- if ([sender tag]==0) { // Want to connect a datasource
- dsConnector = [[TDataSourceConnector alloc] init];
- [dsConnector setSource:object];
- [dsConnector setDestination:[NXApp connectDestination]];
- [[NXApp activeDocument] addConnector:dsConnector];
- [object setDataSource:[dsConnector destination]];
- [[[dsConnector destination] class] methodSelectors:accessorStorage
- includeAncestors:YES
- filterWith:isAccessor];
- [accessorBrowser loadColumnZero];
- [sourceConnectButton setTitle:"Disconnect"];
- [sourceConnectButton setTag:1];
- [sourceDisplayButton setEnabled:YES];
- [sourceDisplayButton setTitle:[[dsConnector destination] name]];
- } else if ([sender tag]==1) { // Want to disconnect a datasource
- [[NXApp activeDocument] removeConnector:dsConnector];
- [dsConnector free];
- [accessorStorage empty];
- [accessorBrowser loadColumnZero];
- [sourceConnectButton setTitle:"Connect"];
- [sourceConnectButton setTag:0];
- [sourceDisplayButton setEnabled:NO];
- [sourceDisplayButton setTitle:""];
- }
- return self;
- }
-
- - showConnection:conn
- {
- const char *dsa, *ia;
- char *str;
-
- // do the accessorBrowser
- dsa = sel_getName([[conn binder] dataSourceAccessor]);
- ia = sel_getName([[conn binder] interfaceAccessor]);
- str = malloc((dsa?strlen(dsa):0)+(ia?strlen(ia):0)+10);
- if (dsa && ia)
- sprintf(str,"/%s/%s",dsa,ia);
- else if (dsa)
- sprintf(str,"/%s",dsa);
- [accessorBrowser setPath:str];
- free(str);
-
- return self;
- }
-
- - selectConnection:sender
- {
- id conn = [connectorList objectAt:[[browser matrixInColumn:0] selectedRow]];
-
- if (!conn) return self;
-
- selecting = YES;
- // draw the connection
- [NXApp displayConnectionBetween:[conn source] and:[conn destination]];
- [accessorBrowser loadColumnZero];
- [self showConnection:conn];
-
- [connectButton setTitle:"Disconnect"];
- [connectButton setTag:1];
- [connectButton setEnabled:YES];
-
- return self;
- }
-
- - constructBinder
- { //Assumes [NXApp isConnecting].
- id binder;
-
- binder = [[TBinder alloc] init];
-
- // we set up the datasource after reading all connections
- [binder setInterface:[NXApp connectDestination]];
- [binder setDataSource:nil];
-
- if ([[accessorBrowser matrixInColumn:0] selectedCell]) {
- [binder setDataSourceAccessor:
- sel_getUid([[[accessorBrowser matrixInColumn:0] selectedCell]
- stringValue])];
- [binder setDataSourceModifier:
- modifierFor([binder dataSourceAccessor])];
- }
- if ([[accessorBrowser matrixInColumn:1] selectedCell]) {
- [binder setInterfaceAccessor:
- sel_getUid([[[accessorBrowser matrixInColumn:1] selectedCell]
- stringValue])];
- [binder setInterfaceModifier:
- modifierFor([binder interfaceAccessor])];
- }
- return binder;
- }
-
- - ok:sender
- {
- int i;
- id aConnector, b;
-
- if ([sender tag]==0) { // Want to connect a binder
- aConnector = [[TConnector alloc] init];
- [aConnector setBinder:[self constructBinder] andSource:object];
- [[NXApp activeDocument] addConnector:aConnector];
- [connectorList addObject:aConnector];
- [browser loadColumnZero];
- b = [browser matrixInColumn:0];
- [b selectCellAt:[b cellCount]-1 :0];
- [connectButton setTitle:"Disconnect"];
- [connectButton setTag:1];
- } else if ([sender tag] ==1) { // Want to disconnect a binder
- i = [[browser matrixInColumn:0] selectedRow];
- aConnector = [connectorList removeObjectAt:i];
-
- [[NXApp activeDocument] removeConnector:aConnector];
- [aConnector free];
- [browser loadColumnZero];
- [[browser matrixInColumn:0] selectCellAt:-1 :-1];
- [connectButton setTitle:"Connect"];
- [connectButton setTag:0];
- }
- return [super ok:sender];
- }
-
- - revert:sender
- {
- int s,cond;
- id dsConnector = getDSConnectorForSource(object);
-
- if (selecting) {
- selecting = NO;
- return self;
- }
-
- if (![inspectorView isDescendantOf:[window contentView]]) {
- id biv = [binderInspector inspectorView];
- [[biv superview] replaceSubview:biv with:inspectorView];
- [[inspectorView window] display];
- }
- if (dsConnector) {
- [sourceDisplayButton setEnabled:YES];
- [sourceDisplayButton setTitle:
- [[dsConnector destination] name]];
- cond = ([NXApp isConnecting] &&
- [dsConnector destination]==[NXApp connectDestination]);
- [sourceDisplayButton setState:cond];
- [sourceConnectButton setTitle:"Disconnect"];
- [sourceConnectButton setTag:1];
- [[[dsConnector destination] class] methodSelectors:accessorStorage
- includeAncestors:YES
- filterWith:isAccessor];
- } else {
- [sourceDisplayButton setEnabled:NO];
- [sourceDisplayButton setTitle:""];
- [sourceConnectButton setTitle:"Connect"];
- [sourceConnectButton setTag:0];
- }
- [sourceConnectButton setEnabled:[NXApp isConnecting]];
-
- [[NXApp activeDocument] listConnectors:connectorList forSource:object
- filterClass:[TConnector class]];
- [browser loadColumnZero];
- [accessorBrowser loadColumnZero];
-
- if ([NXApp isConnecting]) {
- s = [connectorList indexOf:
- getTConnectorForDestination([NXApp connectDestination])];
- if (s == NX_NOT_IN_LIST) {
- [[browser matrixInColumn:0] selectCellAt:-1 :-1];
- [connectButton setTitle:"Connect"];
- [connectButton setTag:0];
- [connectButton setEnabled:YES];
- } else {
- [accessorBrowser loadColumnZero];
- [self showConnection:[connectorList objectAt:s]];
- [[browser matrixInColumn:0] selectCellAt:s :0];
- [connectButton setTitle:"Disconnect"];
- [connectButton setTag:1];
- [connectButton setEnabled:YES];
- }
- } else {
- [[browser matrixInColumn:0] selectCellAt:-1 :-1];
- [connectButton setTitle:"No Selection"];
- [connectButton setEnabled:NO];
- [connectButton setTag:2];
- }
-
- return [super revert:sender];
- }
-
- - (BOOL)wantsButtons
- {
- return NO;
- }
-
- @end
-
- @implementation TBinderList (ConnectionsInspector)
-
- -(const char *)getConnectInspectorClassName
- {
- NXEvent *ev = [NXApp currentEvent];
-
- // NOTE: This doesn't work on PC's and most NextStations, due
- // to the fact that control-alt is mapped to be a Help key!!!
- // expect this to go away later with the more complete version of
- // superclass-inspector access.
- if (ev->flags & NX_ALTERNATEMASK)
- return [super getConnectInspectorClassName];
- else
- return "TBinderListConnectInspector";
- }
-
- -(const char *)getEditorClassName
- {
- NXEvent *ev = [NXApp currentEvent];
-
- // lets try not to confuse people... unless they really want
- // to be confused!!!
- if (ev->flags & NX_ALTERNATEMASK)
- return [super getConnectInspectorClassName];
- else
- return NULL;
- }
-
- - (NXImage *)getIBImage
- {
- return [NXImage findImageNamed:"TBinderListIcon"];
- }
-
- @end
-
-